//-------------------------------------------------------------------
//	Copyright (c) 2010-2012  Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_ENUMS_H
#define _UX_ENUMS_H

#include "../Defines/Defines.h"

namespace Engine
{

//============================= Render ============================//
//=================================================================//

// -------------------------- Light Type ------------------------- //

namespace e_light
{
	enum	type :	uint8
	{
		UNKNOWN		= 0,
		DIRECTIONAL,
		SPOT,
		OMNI,

		_COUNT
	};

	enum	bits :	uint32
	{
		UNKNOWN_BIT		= 0,
		DIRECTIONAL_BIT	= bits(1) << DIRECTIONAL,
		SPOT_BIT		= bits(1) << SPOT,
		OMNI_BIT		= bits(1) << OMNI,
		ALL_BITS		= 0xFFFFFFFF,
	};
}
UX_ENUM_META_OBJECT( e_light::type );


// ------------------------- Shadow Type ------------------------- //

namespace e_shadow
{
	enum	type :	uint8
	{
		UNKNOWN		= 0,
		SIMPLE_SM,
		CASCADED_SM,
		PERSPECTIVE_SM,
		PARALLEL_SPLIT_SM,

		_COUNT
	};

	enum	bits :	uint32
	{
		UNKNOWN_BITS			= 0,
		SIMPLE_SM_BIT			= bits(1) << SIMPLE_SM,
		CASCADED_SM_BIT			= bits(1) << CASCADED_SM,
		PERSPECTIVE_SM_BIT		= bits(1) << PERSPECTIVE_SM,
		PARALLEL_SPLIT_SM_BIT	= bits(1) << PARALLEL_SPLIT_SM,
		ALL_BITS				= 0xFFFFFFFF,
	};
}
UX_ENUM_META_OBJECT( e_shadow::type );


// ------------------------- Camera Type ------------------------- //

namespace e_camera
{
	enum	type	: uint8
	{
		UNKNOWN		= 0,
		VIEW,			// view camera
		MINI_VIEW,		// mini view camera
		LIGHT,			// shadow cast light camera
		REFLECTION,		// camera for render reflections

		_COUNT
	};
}
UX_ENUM_META_OBJECT( e_camera::type );


// ---------------------- Vertex Attrib Type --------------------- //

namespace e_vertex_attrib
{
	enum	type	: uint8
	{
		UNKNOWN		= uint8(-1),

		LOCATION_0	= 0,
		LOCATION_1,
		LOCATION_2,
		LOCATION_3,
		LOCATION_4,
		LOCATION_5,
		LOCATION_6,
		LOCATION_7,
		LOCATION_8,
		LOCATION_9,
		LOCATION_10,
		LOCATION_11,
		LOCATION_12,
		LOCATION_13,
		LOCATION_14,
		LOCATION_15,
		LOCATION_16,
		LOCATION_17,

		// Default //
		POSITION	= LOCATION_0,
		TEXCOORD_0	= LOCATION_2,
		TEXCOORD_1	= LOCATION_3,
		TEXCOORD_2	= LOCATION_4,
		TEXCOORD_3	= LOCATION_5,
		TEXCOORD_4	= LOCATION_6,
		TEXCOORD_5	= LOCATION_7,
		TEXCOORD_6	= LOCATION_8,
		TEXCOORD_7	= LOCATION_9,
		TEXCOORD_8	= LOCATION_10,
		TEXCOORD_9	= LOCATION_11,
		TEXCOORD_10	= LOCATION_12,
		TEXCOORD_11	= LOCATION_13,
		TEXCOORD_12	= LOCATION_14,
		TEXCOORD_13	= LOCATION_15,
		TEXCOORD_14	= LOCATION_16,
		TEXCOORD_15	= LOCATION_17,
		DIFFUSE		= TEXCOORD_0,
		
		// 2D //
		COLOR_0		= LOCATION_1,
		COLOR_1		= TEXCOORD_1,
		COLOR_2		= TEXCOORD_3,
		QUAD_DEPTH	= TEXCOORD_1,	// quad depth if use geometry shader

		// 3D //
		NORMAL		= LOCATION_1,
		TANGENT		= TEXCOORD_1,
		BINORMAL	= TEXCOORD_2,
		WEIGHTS		= POSITION,		// for sceletal mesh only
	};
}
UX_ENUM_META_OBJECT( e_vertex_attrib::type );


// -------------------- Default Program Type -------------------- //
/*
namespace e_def_program
{
	enum	type	: uint8
	{
		UNKNOWN		= 0,
		FONT,				// for font drawing (pos, tex, col)
		SIMPLE_2D,			// for drawing 2d (pos, tex, col)
		SIMPLE_2D_COLOR,	// for drawing 2d without texturing
		SIMPLE_3D,			// for drawing 3d (pos, norm, tex ...)
		SIMPLE_3D_CM,		// for drawing 3d with cubemap
		FONT_GS,			// use geometry shader to build quads
		SIMPLE_2D_GS,		// use geometry shader to build quads
		SIMPLE_2D_COLOR_GS,	// use geometry shader to build quads
		_COUNT
	};
}
UX_ENUM_META_OBJECT( e_def_program::type );
*/

// ------------------------ Combine Mode ------------------------- //
/*
namespace e_combine_mode
{
	enum	type	: uint8
	{
		REPLACE			= 0,
		MODULATE		= 1,
		ADD				= 2,
		ADD_SIGNED		= 3,
		SUBTRACT		= 4,
		REPLACE_ALPHA	= 5,
	};
}
UX_ENUM_META_OBJECT( e_combine_mode::type );
*/


// ----------------- Render State Lock Type ---------------------- //
/*
namespace e_render_state_lock
{
	enum	type	: uint8
	{
		UNKNOWN		= 0,
		BLENDING	= 0x01,
		DEPTH		= 0x02,
		STENCIL		= 0x04,
		CULLING		= 0x08,
		COLOR		= 0x10,
		ALL			= 0xFF
	};

	UX_ENUM_BIT_OPERATIONS( type )
}
UX_ENUM_META_OBJECT( e_render_state_lock::type );
*/

// -------------------- Render Layer Type ------------------------ //

namespace e_render_layer
{
	enum	type	: uint8
	{
		LAYER_1		= 0,
		//...
		LAYER_32	= 31,
		_LAST_LAYER	= LAYER_32,
		
		// default layers //
		SHADOW_MAP_0	= LAYER_1,
		SHADOW_MAP_1,
		SHADOW_MAP_2,
		DEPTH_ONLY_0,
		DEPTH_ONLY_1,
		DEPTH_ONLY_2,
		BACKGROUND_0,
		BACKGROUND_1,
		BACKGROUND_2,
		OPAQUE_0,
		OPAQUE_1,
		OPAQUE_2,
		OPAQUE_3,
		OPAQUE_4,
		OPAQUE_5,
		OPAQUE_6,
		OPAQUE_7,
		OPAQUE_8,
		OPAQUE_9,
		OPAQUE_10,
		OPAQUE_11,
		OPAQUE_12,
		OPAQUE_13,
		OPAQUE_14,
		OPAQUE_15,
		FOREGROUND_0,
		FOREGROUND_1,
		FOREGROUND_2,
		EMISSION_0,
		EMISSION_1,
		EMISSION_2,
		TRANSLUCENT,

		// limits //
		DEPTH_ONLY_FIRST	= DEPTH_ONLY_0,
		DEPTH_ONLY_LAST		= DEPTH_ONLY_2,
		SHADOW_MAP_FIRST	= SHADOW_MAP_0,
		SHADOW_MAP_LAST		= SHADOW_MAP_2,
		BACKGROUND_FIRST	= BACKGROUND_0,
		BACKGROUND_LAST		= BACKGROUND_2,
		OPAQUE_FIRST		= OPAQUE_0,
		OPAQUE_LAST			= OPAQUE_15,
		FOREGROUND_FIRST	= FOREGROUND_0,
		FOREGROUND_LAST		= FOREGROUND_2,
		EMISSION_FIRST		= EMISSION_0,
		EMISSION_LAST		= EMISSION_2,
		TRANSLUCENT_FIRST	= TRANSLUCENT,
		TRANSLUCENT_LAST	= TRANSLUCENT,

		// for view camera //
		VIEW_CAMERA_FIRST	= BACKGROUND_FIRST,
		VIEW_CAMERA_LAST	= TRANSLUCENT_LAST,

		// for shadow camera //
		SHADOW_CAMERA_FIRST	= SHADOW_MAP_FIRST,
		SHADOW_CAMERA_LAST	= SHADOW_MAP_LAST,
		
		SINGLE_SHADOW_MAP	= SHADOW_MAP_0,
		LAYERED_SHADOW_MAP	= SHADOW_MAP_1,

		UNKNOWN				= type(-1),
		DEFAULT				= OPAQUE_0,
		BATCH_LAYER			= OPAQUE_1,		// used in CBatchRender
	};
	UX_ENUM_ADD_OPERATIONS( type );


	enum	bits	: uint32
	{
		UNKNOWN_BIT			= 0,
		ALL_BITS			= bits(-1),
		LAYER_1_BIT			= bits(1) << LAYER_1,
		//...
		LAYER_32_BIT		= bits( bits(1) << LAYER_32 ),

		SHADOW_MAP_BITS		= ( (bits(1) << (SHADOW_MAP_LAST+1))  -1 ) ^ ( (bits(1) << (SHADOW_MAP_FIRST+1))  -1 ),
		DEPTH_ONLY_BITS		= ( (bits(1) << (DEPTH_ONLY_LAST+1))  -1 ) ^ ( (bits(1) << (DEPTH_ONLY_FIRST+1))  -1 ),
		BACKGROUND_BITS		= ( (bits(1) << (BACKGROUND_LAST+1))  -1 ) ^ ( (bits(1) << (BACKGROUND_FIRST+1))  -1 ),
		OPAQUE_BITS			= ( (bits(1) << (OPAQUE_LAST+1))	  -1 ) ^ ( (bits(1) << (OPAQUE_FIRST+1))		  -1 ),
		FOREGROUND_BITS		= ( (bits(1) << (FOREGROUND_LAST+1))  -1 ) ^ ( (bits(1) << (FOREGROUND_FIRST+1))  -1 ),
		//EMISSION_BITS		= ( (bits(1) << (EMISSION_LAST+1))    -1 ) ^ ( (bits(1) << (EMISSION_FIRST+1))    -1 ),
		//TRANSLUCENT_BITS	= ( (bits(1) << (TRANSLUCENT_LAST+1)) -1 ) ^ ( (bits(1) << (TRANSLUCENT_FIRST+1)) -1 ),
		//VIEW_CAMERA_BITS	= ( (bits(1) << (VIEW_CAMERA_LAST+1)) -1 ) ^ ( (bits(1) << (VIEW_CAMERA_FIRST+1)) -1 ),
		SHADOW_CAMERA_BITS	= SHADOW_MAP_BITS,

		SINGLE_SHADOW_MAP_BIT	= bits(1) << SINGLE_SHADOW_MAP,
		LAYERED_SHADOW_MAP_BIT	= bits(1) << LAYERED_SHADOW_MAP,
	};
	UX_ENUM_BIT_OPERATIONS( bits );


	inline bits TypeToBit(const type t)		{ return bits(1) << t; }
	inline type BitToType(const bits b)		{ bits r = b; type c = LAYER_1;  while(r>1) {++c; r>>=1;}  return c; } 
}
UX_ENUM_META_OBJECT( e_render_layer::type );
UX_ENUM_META_OBJECT( e_render_layer::bits );


// --------------------- Render Queue Flags ---------------------- //

namespace e_renqueue_flags
{
	enum	type	: uint8
	{
		UNKNOWN		= 0,
		LIGHTS		= 0x01,
		SHADOWS		= 0x02,
		REFLECTIONS	= 0x04,

		ALL			= 0xFF
	};
}
UX_ENUM_META_OBJECT( e_renqueue_flags::type );


// -------------------- Render Technique Type -------------------- //

namespace e_technique
{
	enum	type	: uint32
	{
		UNKNOWN					= 0,

		// light techniques //
		//------------------//

		// deferred //
		DEFERRED_SHADING		= 0x00000001,
		LIGHT_PRE_PASS			= 0x00000002,

		// forward lighting //
		FORWARD_LIGHTING		= 0x00000003,

		// ray casting //
		RAY_CASTING				= 0x00000004,

		// ray trasing //
		RAY_TRASING				= 0x00000005,

		_LIGHT_TECH_MASK		= 0x000000FF,


		// shadow techniques //
		//-------------------//

		// shadow mapping //
		SIMPLE_SM				= 0x00000100,		// SSM
		PARALLEL_SPLIT_SM		= 0x00000200,		// PSSM
		CASCADED_SM				= 0x00000400,		// CSM
		PERSPECTIVE_SM			= 0x00000800,		// PSM
		CAMERA_SPACE_SM			= 0x00001000,		// CSSM

		// shadow volume //
		SHADOW_VOLUME			= 0x00010000,

		//PHOTON_MAPPING			= 0x00020000,

		// preganerated shadows //
		OCCLUSION_INTERVAL_SM	= 0x10000000,		// for terrain

		_SHADOW_TECH_MASK		= 0xFFFFFF00,
	};

	UX_ENUM_BIT_OPERATIONS( type )
}
UX_ENUM_META_OBJECT( e_technique::type );



//======================== ResourceManager ========================//
//=================================================================//

// ---------------- Resource Type Delete Method ------------------ //

namespace e_res_delete
{
	enum	type :	uint8
	{
		UNKNOWN		= 0,
		NEVER,				// resman can't delete resource
		NO_REF,				// delete if reference count is 0
	};
}
UX_ENUM_META_OBJECT( e_res_delete::type );


// -------------------- Resource Manager Flags ------------------- //

namespace e_resman_flags
{
	enum	type :	uint8
	{
		UNKNOWN			= 0,
		FREE_NON_REF	= 0x01,		// resman can free non ref resources 
		SET_DEFAUL_RES	= 0x02,		// set default resource if loading failed
	};

	UX_ENUM_BIT_OPERATIONS( type )
}
UX_ENUM_META_OBJECT( e_resman_flags::type );


// ---------------------- Resource Group Type -------------------- //

namespace e_res_group
{
	enum	type :	uint8
	{
		UNKNOWN	= 0,
		RES_DEFAULT,	// without id's
		RES_FILENAME,	// id - filename
		RES_ID,			// id - uid

		_MAX_GROUPS	= (1 << (sizeof(type)<<3)) - 1,
	};
}



//============================ Other ==============================//
//=================================================================//

// --------------------- Render Target Flags --------------------- //

namespace e_rt_flags
{
	enum	type	: uint16
	{
		UNKNOWN				= 0,

		// used in
		RENDER_TECHNIQUE	= 0x0001,
		POSTPROCESS			= 0x0002,

		// flags
		OUTPUT				= 0x0010,
	};

	UX_ENUM_BIT_OPERATIONS( type )
}
UX_ENUM_META_OBJECT( e_rt_flags::type );


// ------------------------- Plugin Type ------------------------- //

namespace e_eng_plugin
{
	enum	type	: uint32
	{
		UNKNOWN		= 0,
	};
}
UX_ENUM_META_OBJECT( e_eng_plugin::type );

//-------------------------------------------------------------------

}	// Engine

#endif	// _UX_ENUMS_H